package suncertify.view.client;

import suncertify.service.Service;
import suncertify.service.ServiceEvent;
import suncertify.view.AsyncActionListener;
import suncertify.view.SwingUtils;
import suncertify.util.Notification;
import suncertify.util.Messages;

import javax.swing.*;
import javax.swing.border.EtchedBorder;
import java.util.Observer;
import java.util.Observable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


/**
 * WaitDialog is titleless dialog for displaying wait
 * message for user and block parent frame for time.
 * Dialog is displayed after record lock attempt 
 */
public class WaitDialog extends JDialog implements Observer {
    private static final Messages msg = Messages.getInstance();
    private static final int LOCK_WAIT_TIME = 500;
    private final JButton cancelButton;
    private Timer timer;
    private JFrame parent;

    /**
     * constructor
     * @param parent parent frame
     * @param service data service
     */
    public WaitDialog(final JFrame parent, final Service service) {
        super(parent, msg.get("ui.client.wait.title"), true);
        this.parent = parent;
        this.setResizable(false);
        this.setUndecorated(true);

        JPanel pane = new JPanel();
        pane.setOpaque(true);
        pane.add(new JLabel(msg.get("ui.client.wait.message")));
        pane.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
        cancelButton = new JButton(msg.get("ui.client.wait.cancel"));
        cancelButton.addActionListener(new AsyncActionListener() {
            public void doAsync(ActionEvent event) {
                service.cancelLocking();
            }
        });
        pane.add(cancelButton);
        service.addObserver(this);
        this.setContentPane(pane);
        this.pack();
    }

    /**
     * updates the current view componen state
     * @param observable event source
     * @param o event object sent to observers
     */
    public void update(Observable observable, Object o) {
        if (!(o instanceof Notification)) {
            return;
        }
        final Notification n = (Notification) o;

        final JDialog dlg = this;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                switch ((ServiceEvent) n.getEvent()) {
                    case LOCKING:
                        timer = new Timer(LOCK_WAIT_TIME, new ActionListener() {
                            public void actionPerformed(ActionEvent actionEvent) {
                                SwingUtils.placeCenter(parent, dlg);
                                dlg.setVisible(true);
                            }
                        });
                        timer.start();
                        break;
                    case ROW_REMOVED:
                    case LOCKED:
                        timer.stop();
                        setVisible(false);
                        break;
                    case LOCK_CANCELLING:
                        cancelButton.setEnabled(false);
                        break;
                    case LOCK_CANCELLED:
                        timer.stop();
                        setVisible(false);
                        cancelButton.setEnabled(true);
                        break;
                    case ERROR:
                        if (isVisible()) {
                            timer.stop();
                            setVisible(false);
                        }
                        break;
                }
            }
        });
    }
}
